package com.eugene.process;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.eugene.element.Calculable;
import com.eugene.element.CurveBucket;
import com.eugene.element.FnCalendar;
import com.eugene.element.FxRate;
import com.eugene.element.IntRate;
import com.eugene.element.IrCurve;
import com.eugene.element.MarketVariable;
import com.eugene.element.MarketVariableDetail;
import com.eugene.element.StockIndex;
import com.eugene.util.HibernateUtil;
import com.martiansoftware.jsap.JSAP;
import com.martiansoftware.jsap.JSAPResult;

public class WriteScenario {
	private final static Logger logger = 
		LoggerFactory.getLogger(WriteScenario.class);
	
	public static void writeScenario(FnCalendar baseDate){
		Session s = HibernateUtil.currentSession();
		Transaction tx = s.beginTransaction();
		
		Query qr =s.createQuery("select distinct a.mvDetailId from Scenario a");
		
		List<String> list  = new ArrayList<String>();
		list=qr.list();
    	for (String cc : list){
    		logger.info("Run with Scenario Set Name {}", cc);
    		writeScenario(cc,baseDate);
    	}
		s.close();
	}
	
	public static void writeScenario(String sceSetId, FnCalendar baseDate){
		Session s = HibernateUtil.currentSession();
		Transaction tx = s.beginTransaction();
		Query qr = s.createQuery("select distinct a.mvDetailName from Scenario as a  " +
								 "where a.mvDetailId= :param ");
		qr.setParameter("param", sceSetId);

		List<String> list = new ArrayList<String>();
		list=qr.list();
		
		for (String cc : list){
    		logger.info("Run with Scenario Set Name {}, Scenario Id {} ", sceSetId,cc);
    		writeScenario(sceSetId,cc,baseDate);
    	}
	}
	
	
	public static void writeScenario(String sceSetId, String sceId, FnCalendar baseDate){
		Session s = HibernateUtil.currentSession();
		Transaction tx = s.beginTransaction();
		
		Query getMv = s.createQuery("select distinct a.refMV.mvId from Scenario as a  " +
  								   "where a.mvDetailId= :param and a.mvDetailName = :param2 " );
		getMv.setParameter("param", sceSetId);
		getMv.setParameter("param2",sceId);
		
		List<String> mvIds = new ArrayList<String>();
    	mvIds =getMv.list();
    	
    	List<MarketVariableDetail> list = new ArrayList<MarketVariableDetail>();
    	List<IntRate> intRates = new ArrayList<IntRate>();
    	
    	for(String xx: mvIds){
    		logger.info("Selected mv {}", xx);
    		Query qr = s.createQuery("from Scenario as a " +
    								 "where a.mvDetailId= :param and a.mvDetailName = :param2 " +
    								 "and a.refMV.mvId = :param3 " );
    		qr.setParameter("param", sceSetId);
    		qr.setParameter("param2",sceId);
    		qr.setParameter("param3",xx);
    		
    		list=qr.list();
    		
    		logger.debug("Output write");
    		logger.debug("Size of MarketVariables : {}" ,list.size());
    		if (list.size() ==0){
    			logger.debug("MarketVariables {} has no Sceaniro under Scenario Set {} " ,xx,sceSetId);
    		}
    		else if(list.get(0).getRefMV().getMvType().equals("IR")){
    			intRates =list.get(0).getRefMV().getMVData(baseDate);
    		}
    		logger.debug("Query Data_SceSetId : {}",list.get(0).getMvDetailId());
    		
    		for (MarketVariableDetail cc : list) {
    			logger.debug("Query Data_SceSetId : {}",cc.getMvDetailId());
    			logger.debug("Query Data_SceId : {}",cc.getMvDetailName());
    			logger.debug("Query Data_MarketVariable : {}",cc.getRefMV().getMvId());
    			logger.debug("Query Data_MarketVariable : {}",cc.getMaturity());
    			logger.debug("Query Data_Coefficient: {}",cc.getCoefficient());
    			logger.debug("Query Data_Power : {}",cc.getPower());
    			logger.debug("Query Data_Spread : {}",cc.getSpread());
    			
    			if (cc.getRefMV().getMvType().equals("IR")){
    				logger.debug("in the IrCurve" );
    				for (IntRate qq : intRates){
    					if (qq.getMaturity().equals(cc.getMaturity())){
    						qq.setIntRateValue(cc.getOperatedIntRate(baseDate, cc.getMaturity()).getIntRateValue());
    					}
    					qq.setIntRateId(xx);
    					qq.setSceSetId(cc.getMvDetailId());
    	    			qq.setSceId(cc.getMvDetailName());
    					
//    					logger.debug("Query Data_Tweaked Value : {},{}",qq.getMaturity(),qq.getValue());
    				}
    			}
    			else if (cc.getRefMV().getMvType().equals("FX")){
    				List<Calculable> kk = cc.getOperatedMVData(baseDate);
    				FxRate pp = new FxRate();	
    				
    				for( Calculable zz: kk){
    					logger.debug("Query Data_Tweaked Value : {}",zz.getValue());
    					pp.setBaseDate(baseDate);
    					pp.setSceSetId(sceSetId);
    					pp.setSceId(sceId);
    					pp.setFxRateId(xx);
    					pp.setFxRateValue(zz.getValue());
    					s.saveOrUpdate("RstSceFxRateHis",pp);
    				}
    				if (kk.size() == 0 ){
    					logger.warn("There are no data with given MarketVariable {} and BaseDate {}",
    							cc.getRefMV().getMvId(), baseDate);
    				}
    			}
    			else if (cc.getRefMV().getMvType().equals("EQ")){
    				List<Calculable> kk = cc.getOperatedMVData(baseDate);
    				StockIndex pp = new StockIndex();	
    				for( Calculable zz: kk){
    					logger.debug("Query Data_Tweaked Value : {}",zz.getValue());
    					pp.setBaseDate(baseDate);
    					pp.setSceSetId(sceSetId);
    					pp.setSceId(sceId);
    					pp.setStockIndexId(xx);
    					pp.setStockIndexValue(zz.getValue());
    					s.saveOrUpdate("RstSceStockIndexHis",pp);
    				}
    				if (kk.size() == 0 ){
    					logger.warn("There are no data with given MarketVariable {} and BaseDate {}",
    							cc.getRefMV().getMvId(), baseDate);
    				}
    			}
    		}
    		
    		for (IntRate qq: intRates){
    			s.saveOrUpdate("RstSceIrCurveHis",qq);
//    			logger.debug("Query Data_sceSet : {}",qq.getSceSetId());
//    			logger.debug("Query Data_sceId : {}",qq.getSceId());
//    			logger.debug("Query Data_IrcId : {}",qq.getIntRateId());
//    			logger.debug("Query Data_date  : {}",qq.getBaseDate());
    			logger.debug("Query Data_Tweaked Value : {},{}",qq.getMaturity(),qq.getValue());
    		}
    	}
    	tx.commit();
//		s.close();
	}
}
